package com.starry.module.system.core.oauth2.authorization.third.impl;

import com.starry.core.common.execption.ServiceException;
import com.starry.db.core.enums.DBEnableDisableStatusEnum;
import com.starry.module.system.core.oauth2.authorization.third.AbstractThireClient;
import com.starry.module.system.core.oauth2.authorization.third.ThireClient;
import com.starry.module.system.core.oauth2.authorization.third.ThireClientFactory;
import com.starry.module.system.core.oauth2.authorization.third.client.ThireClientGitee;
import com.starry.module.system.core.oauth2.authorization.third.client.ThireClientGithub;
import com.starry.module.system.core.oauth2.authorization.third.client.ThireClientWxCharMini;
import com.starry.module.system.core.oauth2.entity.Oauth2ThirdClient;
import com.starry.module.system.core.oauth2.service.Oauth2ThirdClientService;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static com.starry.module.system.core.oauth2.authorization.constant.SecurityConstants.*;

/**
 * 获取第三方认证客户端
 *
 * @author xiaoke
 */
@Service
public class ThireClientFactoryImpl implements ThireClientFactory {

    /**
     * 第三方认证客户端 Map
     * key：配置编号
     */
    private final ConcurrentMap<String, AbstractThireClient> clients = new ConcurrentHashMap<>();


    private final Oauth2ThirdClientService thirdClientService;


    public ThireClientFactoryImpl(Oauth2ThirdClientService thirdClientService) {
        this.thirdClientService = thirdClientService;
    }

    @Override
    public ThireClient getClient(String code) throws Exception {
        // 缓存中获取
        AbstractThireClient client = clients.get(code);
        if (client != null) {
            return client;
        }

        Oauth2ThirdClient clientConfig = thirdClientService.getByClientCode(code);
        if (clientConfig == null) {
            throw new ServiceException("第三方认证客户端不存在");
        }

        if (DBEnableDisableStatusEnum.isDisable(clientConfig.getStatus())) {
            throw new ServiceException("该第三方认证客户端已禁用");
        }

        return createClient(clientConfig);
    }

    @Override
    public void reloadClient(Oauth2ThirdClient oauth2ThirdClient) throws Exception {
        clients.remove(oauth2ThirdClient.getCode());
        createClient(oauth2ThirdClient);
    }

    /**
     * 创建第三方认证客户端
     *
     * @param clientConfig 第三方认证客户端配置
     * @return AbstractThireClient
     */
    private AbstractThireClient createClient(Oauth2ThirdClient clientConfig) {
        // 根据类型创建
        AbstractThireClient client = switch (clientConfig.getCode()) {
            case THIRD_LOGIN_GITEE -> new ThireClientGitee(clientConfig.getCode(), clientConfig);
            case THIRD_LOGIN_GITHUB -> new ThireClientGithub(clientConfig.getCode(), clientConfig);
            case THIRD_LOGIN_WX_CHAT_MINI -> new ThireClientWxCharMini(clientConfig.getCode(), clientConfig);
            default -> null;
        };

        if (client == null) {
            throw new ServiceException("第三方认证客户端不存在");
        }

        // 缓存中添加
        clients.put(clientConfig.getCode(), client);

        return client;
    }
}
